const WebSocket = require('ws');
// 设置直播间号
const ROOM_ID = 762505; // Replace with the actual room ID
class SocketService {
    static instance = null;
    // 和服务端连接的socket对象
    ws = null;
    // 存储回调函数
    callBackMapping = {};
    // 标识是否连接成功
    connected = false;

    static get Instance() {
        if (!this.instance) {
            this.instance = new SocketService();
        }
        return this.instance;
    }

    //  定义连接服务器的方法
    connect() {
        // 判断是否已经连接, 如果已经连接, 则不重复连接
        if (this.connected) {
            return;
        }
        let url = 'wss://danmuproxy.douyu.com:8506/';
        this.ws = new WebSocket(url);
        // 连接成功的事件
        this.ws.onopen = () => {
            console.log('连接服务端成功');
            this.connected = true;
            this.initDouYuApi();
        };
        // 1.连接服务端失败
        // 2.当连接成功之后, 服务器关闭的情况
        this.ws.onclose = () => {
            console.log('接口连接断开');
            this.connected = false;
        };
        // 得到服务端发送过来的数据
        this.ws.onmessage = msg => {
            // console.log(msg.data, '从服务端获取到了数据');
            this.parseDouyuMessage(msg.data)
        };
    }

    // 初始化斗鱼弹幕服务器
    initDouYuApi() {
        console.log('初始化斗鱼弹幕服务器');
        const str = 'type@=loginreq/roomid@=' + ROOM_ID + '/dfl@=/username@=test/uid@=123456/ver@=20230722/aver@=218101901/ct@=0/';
        this.send(str);
        // 发送加入分组消息
        const str1 = "type@=joingroup/rid@=1/gid@=-9999/";
        this.send(str1);
        // 发送心跳包
        setInterval(() => {
            this.send("type@=mrkl/");
        }, 45000);
    }

    // 获取连接状态
    getConnected() {
        return this.connected;
    }

    // 关闭连接的方法
    closeWs() {
        if (this.connected) {
            this.ws.close()
        }
        console.log('WS关闭中..');
    }

    // 获取直播间号
    getRoomId() {
        return ROOM_ID;
    }

    // 回调函数的注册
    registerCallBack(socketType, callBack) {
        this.callBackMapping[socketType] = callBack;
    }

    // 取消某一个回调函数
    unRegisterCallBack(socketType) {
        this.callBackMapping[socketType] = null;
    }

    // 解析斗鱼消息
    parseDouyuMessage(data) {
        // 由于数据是二进制数据，需要解析头部的消息长度字段来获取完整的消息数据
        const msgLength = data.readUInt32LE(0); // 从0号位置读取4字节的小端整数
        // 处理弹幕服务器发送给客户端的文本格式数据
        // 去掉头部长度字段和最后的'\0'
        const retData = data.toString('utf8', 12, msgLength - 1);
        // 对回调函数进行数据返回
        this.callBackMapping['chatmsg'](retData);
    }

    // 发送数据的方法
    send(data) {
        // 判断此时此刻有没有连接成功
        if (!this.connected) {
            return
        }
        console.log('发送数据:', data)
        data += '\0';
        const len = data.length;
        const buffer = new ArrayBuffer(len + 12);
        new DataView(buffer).setInt16(0, len + 8, true);
        new DataView(buffer).setInt16(4, len + 8, true);
        new DataView(buffer).setInt16(8, 45314, false);
        const bufView = new Uint8Array(buffer, 12);
        for (let i = 0; i < len; i++) {
            bufView[i] = data.charCodeAt(i);
        }
        this.ws.send(buffer);
    }
}

module.exports = SocketService;
